import { HttpException, HttpStatus, Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { DataSource, Repository } from 'typeorm'
import { BaseService } from '@/common/base/base.service'
import { PlayerUser } from '../user/entities/player-user.entity'
import { UserWheelTask } from './entities/user-wheel-task.entity'
import { WheelTask } from './entities/wheel-task.entity'

@Injectable()
export class WheelTaskService extends BaseService<WheelTask> {
  constructor(
    @InjectRepository(WheelTask)
    private readonly wheelTaskRepo: Repository<WheelTask>,
    @InjectRepository(UserWheelTask)
    private readonly userWheelTaskRepo: Repository<UserWheelTask>,
    @InjectRepository(PlayerUser)
    private readonly playerUserRepo: Repository<PlayerUser>,
    private readonly dataSource: DataSource,
  ) {
    super(wheelTaskRepo)
  }

  async completeTask(userUid: string, wheelTaskId: number) {
    return await this.dataSource.transaction(async (manager) => {
      // 1️⃣ 获取任务模板
      const task = await manager.findOne(WheelTask, {
        where: { wheelTaskId, isEnabled: true },
      })
      if (!task) {
        return new HttpException('任务不存在或未启用', HttpStatus.BAD_REQUEST)
      }

      // 2️⃣ 查找或创建用户任务记录
      let userTask = await manager.findOne(UserWheelTask, {
        where: { userUid, wheelTaskId },
        relations: ['wheelTask'],
      })
      if (!userTask) {
        userTask = manager.create(UserWheelTask, {
          userUid,
          wheelTaskId,
          usedCount: 0,
        })
      }

      if (userTask.isCompleted) {
        throw new HttpException('任务已完成', HttpStatus.BAD_REQUEST)
      }

      //  更新用户任务记录
      userTask.completedCount += 1
      await manager.save(UserWheelTask, userTask)

      // 更新用户可用抽奖次数
      await manager.increment(PlayerUser, { uid: userUid }, 'canDrawCount', task.drawCount)
    })
  }

  async upsertUserTask(uid: string) {
    const tasks = await this.wheelTaskRepo.find({ where: { isEnabled: true } })

    if (!tasks.length)
      return

    const existUserTasks = await this.userWheelTaskRepo.find({ where: { userUid: uid }, select: ['wheelTaskId'] })

    const existTaskIds = new Set(existUserTasks.map(t => t.wheelTaskId))
    const insertTasks = tasks
      .filter(task => !existTaskIds.has(task.wheelTaskId))
      .map(task => ({
        userUid: uid,
        wheelTaskId: task.wheelTaskId,
        completedCount: 0,
      }))

    if (insertTasks.length > 0) {
      await this.userWheelTaskRepo.save(insertTasks)
    }
  }

  async findUserTasks(uid: string) {
    const response = await this.userWheelTaskRepo.find({
      where: { userUid: uid },
      relations: ['wheelTask'],
    })
    return response
  }
}
